"""
配置管理模块
"""

import yaml
from pathlib import Path
from typing import Dict, Any, List
from dataclasses import dataclass


@dataclass
class AppConfig:
    """应用配置"""
    name: str = "ONVIF Camera Manager"
    version: str = "1.0.0"
    debug: bool = False


@dataclass
class DiscoveryConfig:
    """发现配置"""
    enabled: bool = True
    timeout: int = 10
    multicast_address: str = "239.255.255.250"
    multicast_port: int = 3702
    network_ranges: List[str] = None
    
    def __post_init__(self):
        if self.network_ranges is None:
            self.network_ranges = ["192.168.1.0/24"]


@dataclass
class PingConfig:
    """Ping配置"""
    enabled: bool = True
    interval: int = 30
    timeout: int = 5
    packet_count: int = 5


@dataclass
class PortCheckConfig:
    """端口检查配置"""
    enabled: bool = True
    timeout: int = 5
    ports: List[int] = None
    
    def __post_init__(self):
        if self.ports is None:
            self.ports = [80, 8080, 554, 8554]


@dataclass
class OfflineDevicesConfig:
    """离线设备管理配置"""
    retention_minutes: int = 5
    cleanup_interval: int = 60


@dataclass
class MonitoringConfig:
    """监控配置"""
    enabled: bool = True
    ping: PingConfig = None
    port_check: PortCheckConfig = None
    offline_devices: OfflineDevicesConfig = None

    def __post_init__(self):
        if self.ping is None:
            self.ping = PingConfig()
        if self.port_check is None:
            self.port_check = PortCheckConfig()
        if self.offline_devices is None:
            self.offline_devices = OfflineDevicesConfig()


@dataclass
class LoggingConfig:
    """日志配置"""
    level: str = "INFO"
    format: str = "{time:YYYY-MM-DD HH:mm:ss} | {level} | {name}:{function}:{line} | {message}"


@dataclass
class PrometheusMetricsConfig:
    """Prometheus指标配置"""
    device_info: bool = True
    device_status: bool = True
    network_performance: bool = True
    service_status: bool = True
    system_stats: bool = True
    discovery_stats: bool = True


@dataclass
class PrometheusLabelsConfig:
    """Prometheus标签配置"""
    instance: str = "onvif-monitor"
    environment: str = "production"
    location: str = "datacenter-1"


@dataclass
class PrometheusConfig:
    """Prometheus配置"""
    enabled: bool = False
    port: int = 9098
    host: str = "0.0.0.0"
    update_interval: int = 30
    metrics: PrometheusMetricsConfig = None
    labels: PrometheusLabelsConfig = None

    def __post_init__(self):
        if self.metrics is None:
            self.metrics = PrometheusMetricsConfig()
        if self.labels is None:
            self.labels = PrometheusLabelsConfig()


class Config:
    """配置管理器"""
    
    def __init__(self, config_path: str = "config/config.yaml"):
        self.config_path = Path(config_path)
        self._load_config()
    
    def _load_config(self):
        """加载配置文件"""
        try:
            if self.config_path.exists():
                with open(self.config_path, 'r', encoding='utf-8') as f:
                    config_data = yaml.safe_load(f) or {}
            else:
                config_data = {}
                
            # 解析配置
            self.app = self._parse_app_config(config_data.get('app', {}))
            self.discovery = self._parse_discovery_config(config_data.get('discovery', {}))
            self.monitoring = self._parse_monitoring_config(config_data.get('monitoring', {}))
            self.logging = self._parse_logging_config(config_data.get('logging', {}))
            self.prometheus = self._parse_prometheus_config(config_data.get('prometheus', {}))
            
        except Exception as e:
            print(f"加载配置文件失败: {e}")
            # 使用默认配置
            self.app = AppConfig()
            self.discovery = DiscoveryConfig()
            self.monitoring = MonitoringConfig()
            self.logging = LoggingConfig()
            self.prometheus = PrometheusConfig()
    
    def _parse_app_config(self, data: Dict[str, Any]) -> AppConfig:
        """解析应用配置"""
        return AppConfig(
            name=data.get('name', 'ONVIF Camera Manager'),
            version=data.get('version', '1.0.0'),
            debug=data.get('debug', False)
        )
    
    def _parse_discovery_config(self, data: Dict[str, Any]) -> DiscoveryConfig:
        """解析发现配置"""
        return DiscoveryConfig(
            enabled=data.get('enabled', True),
            timeout=data.get('timeout', 10),
            multicast_address=data.get('multicast_address', '239.255.255.250'),
            multicast_port=data.get('multicast_port', 3702),
            network_ranges=data.get('network_ranges', ['192.168.1.0/24'])
        )
    
    def _parse_monitoring_config(self, data: Dict[str, Any]) -> MonitoringConfig:
        """解析监控配置"""
        ping_data = data.get('ping', {})
        port_check_data = data.get('port_check', {})
        offline_devices_data = data.get('offline_devices', {})

        ping_config = PingConfig(
            enabled=ping_data.get('enabled', True),
            interval=ping_data.get('interval', 30),
            timeout=ping_data.get('timeout', 5),
            packet_count=ping_data.get('packet_count', 5)
        )

        port_check_config = PortCheckConfig(
            enabled=port_check_data.get('enabled', True),
            timeout=port_check_data.get('timeout', 5),
            ports=port_check_data.get('ports', [80, 8080, 554, 8554])
        )

        offline_devices_config = OfflineDevicesConfig(
            retention_minutes=offline_devices_data.get('retention_minutes', 5),
            cleanup_interval=offline_devices_data.get('cleanup_interval', 60)
        )

        return MonitoringConfig(
            enabled=data.get('enabled', True),
            ping=ping_config,
            port_check=port_check_config,
            offline_devices=offline_devices_config
        )
    
    def _parse_logging_config(self, data: Dict[str, Any]) -> LoggingConfig:
        """解析日志配置"""
        return LoggingConfig(
            level=data.get('level', 'INFO'),
            format=data.get('format', '{time:YYYY-MM-DD HH:mm:ss} | {level} | {name}:{function}:{line} | {message}')
        )

    def _parse_prometheus_config(self, data: Dict[str, Any]) -> PrometheusConfig:
        """解析Prometheus配置"""
        # 解析指标配置
        metrics_data = data.get('metrics', {})
        metrics_config = PrometheusMetricsConfig(
            device_info=metrics_data.get('device_info', True),
            device_status=metrics_data.get('device_status', True),
            network_performance=metrics_data.get('network_performance', True),
            service_status=metrics_data.get('service_status', True),
            system_stats=metrics_data.get('system_stats', True),
            discovery_stats=metrics_data.get('discovery_stats', True)
        )

        # 解析标签配置
        labels_data = data.get('labels', {})
        labels_config = PrometheusLabelsConfig(
            instance=labels_data.get('instance', 'onvif-monitor'),
            environment=labels_data.get('environment', 'production'),
            location=labels_data.get('location', 'datacenter-1')
        )

        return PrometheusConfig(
            enabled=data.get('enabled', False),
            port=data.get('port', 9098),
            host=data.get('host', '0.0.0.0'),
            update_interval=data.get('update_interval', 30),
            metrics=metrics_config,
            labels=labels_config
        )
    
    def reload(self):
        """重新加载配置"""
        self._load_config()
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            'app': {
                'name': self.app.name,
                'version': self.app.version,
                'debug': self.app.debug
            },
            'discovery': {
                'enabled': self.discovery.enabled,
                'timeout': self.discovery.timeout,
                'multicast_address': self.discovery.multicast_address,
                'multicast_port': self.discovery.multicast_port,
                'network_ranges': self.discovery.network_ranges
            },
            'monitoring': {
                'enabled': self.monitoring.enabled,
                'ping': {
                    'enabled': self.monitoring.ping.enabled,
                    'interval': self.monitoring.ping.interval,
                    'timeout': self.monitoring.ping.timeout,
                    'packet_count': self.monitoring.ping.packet_count
                },
                'port_check': {
                    'enabled': self.monitoring.port_check.enabled,
                    'timeout': self.monitoring.port_check.timeout,
                    'ports': self.monitoring.port_check.ports
                }
            },
            'logging': {
                'level': self.logging.level,
                'format': self.logging.format
            }
        }
